//
//  VideoPlayerView.m
//  tagPlayerModule
//
//  Created by liqian on 2018/10/23.
//  Copyright © 2018年 liqian. All rights reserved.
//

#import "VideoPlayerView.h"
@interface VideoPlayerView ()

@property (nonatomic, strong) AVPlayerItem *playerItem;

@property (nonatomic, strong) AVPlayerLayer *playerLayer;

@property (nonatomic, assign) NSInteger currentPlayTime;//当前播放时间（单位: S）

@property (nonatomic, assign) NSInteger totalTime; // 视频总时长（单位： S）

@property (nonatomic,strong) AVPlayer * player;

@property (nonatomic, strong) id timeObserver;
@property (nonatomic, assign) VedioStatus playerStatus;

@end
@implementation VideoPlayerView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
        
    }
    return self;
}

- (void)dealloc
{
    [self destroyPlayer];
    [self removeObserver:self forKeyPath:@"playerStatus"];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)initPlayer{
    
    if([[UIDevice currentDevice] systemVersion].floatValue >= 10.0){
        //      增加下面这行可以解决iOS10兼容性问题了
        if (@available(iOS 10.0, *)) {
            self.player.automaticallyWaitsToMinimizeStalling = NO;
        } else {
            // Fallback on earlier versions
        }
    }
    
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    //视频拉伸模式
    self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
//    self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    self.playerLayer.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    [self.layer insertSublayer:self.playerLayer atIndex:0];
}

- (void)setVideoUrlStr:(NSString *)videoUrlStr{
    _videoUrlStr = videoUrlStr;
    if (self.player) {
        if (self.playerStatus == VedioStatusPause) {
            [self play];
            
        } else {
            [self pause];
            
        }
    } else {
        [self initMusic];
        [self play];
        
    }
    
}
- (void)initMusic {
    self.player = [[AVPlayer alloc]init];
    
    [self initPlayerItem];
    [self addPlayerListener];
    [self initPlayer];
}

//修改playerItem
- (void)initPlayerItem {
    if (self.videoUrlStr && ![self.videoUrlStr isEqualToString:@""]) {
        AVAsset * aset = [AVAsset assetWithURL:[NSURL URLWithString:self.videoUrlStr]];
        self.playerItem = [AVPlayerItem playerItemWithAsset:aset];
        [self.player replaceCurrentItemWithPlayerItem:self.playerItem];
    }
}
//添加监听文件,所有的监听
- (void)addPlayerListener {
    
    //自定义播放状态监听
    [self addObserver:self forKeyPath:@"playerStatus" options:NSKeyValueObservingOptionNew context:nil];
    if (self.player) {
        //播放速度监听
        [self.player addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    if (self.playerItem) {
        //播放状态监听
        [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        //缓冲进度监听
        [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
        [self.playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
        // Will warn you when your buffer is good to go again.
        [self.playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
        //播放中监听，更新播放进度
        __weak typeof(self) weakSelf = self;
        self.timeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 30) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
            float currentPlayTime = (double)weakSelf.playerItem.currentTime.value/weakSelf.playerItem.currentTime.timescale;
            if (weakSelf.playerItem.currentTime.value<0) {
                currentPlayTime = 0.1; //防止出现时间计算越界问题
            }
            
        }];
        
    }
    
    //给AVPlayerItem添加播放完成通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    //监听应用后台切换
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(appEnteredBackground)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];
    //播放中被打断
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
    //拔掉耳机监听？？
}

#pragma mark 播放，暂停
- (void)play{
    if (self.player && self.playerStatus == VedioStatusPause) {
        NSLog(@"通过播放停止");
        self.playerStatus = VedioStatusBuffering;
        [self.player play];
    }
}

- (void)pause{
    if (self.player && self.playerStatus != VedioStatusPause) {
        NSLog(@"通过暂停停止");
//        [self stopAnimation];
        self.playerStatus = VedioStatusPause;
        [self.player pause];
    }
}


#pragma mark 监听播放完成事件
-(void)playerFinished:(NSNotification *)notification{
    NSLog(@"播放完成");
    [self.playerItem seekToTime:kCMTimeZero];
    [self pause];
}

#pragma mark 播放被打断
- (void)handleInterruption:(NSNotification *)notification {
    [self pause];
}

#pragma mark 监听捕获
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerItem *item = (AVPlayerItem *)object;
        if ([self.playerItem status] == AVPlayerStatusReadyToPlay) {
            //获取音频总长度
            CMTime duration = item.duration;
            [self setMaxDuratuin:CMTimeGetSeconds(duration)];
            NSLog(@"AVPlayerStatusReadyToPlay -- 音频时长%f",CMTimeGetSeconds(duration));
            
        }else if([self.playerItem status] == AVPlayerStatusFailed) {
            
            [self playerFailed];
            NSLog(@"AVPlayerStatusFailed -- 播放异常");
            
        }else if([self.playerItem status] == AVPlayerStatusUnknown) {
            
            [self pause];
            NSLog(@"AVPlayerStatusUnknown -- 未知原因停止");
        }
    } else if([keyPath isEqualToString:@"loadedTimeRanges"]) {
        AVPlayerItem *item = (AVPlayerItem *)object;
        NSArray * array = item.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue]; //本次缓冲的时间范围
        NSTimeInterval totalBuffer = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration); //缓冲总长度
        //        self.timeSlider.trackValue = totalBuffer;
        //当缓存到位后开启播放，取消loading
        if ( self.playerStatus != VedioStatusPause && totalBuffer > 1 ) {
            [self.player play];
        }
        NSLog(@"---共缓冲---%.2f",totalBuffer);
    } else if ([keyPath isEqualToString:@"rate"]){
        AVPlayer *item = (AVPlayer *)object;
        if (item.rate == 0) {
            if (self.playerStatus != VedioStatusPause) {
                self.playerStatus = VedioStatusBuffering;
            }
        } else {
            self.playerStatus = VedioStatusPlaying;
            
        }
        NSLog(@"---播放速度---%f",item.rate);
    } else if([keyPath isEqualToString:@"playerStatus"]){
        switch (self.playerStatus) {
            case VedioStatusBuffering:
                
                break;
            case VedioStatusPause:
                
                break;
            case VedioStatusPlaying:
                
                break;
                
            default:
                break;
        }
    }else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
        
        
    }else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
        
        
    }
}
//计算时间
- (NSString *)convertTime:(CGFloat)second{
    NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    if (second/3600 >= 1) {
        [formatter setDateFormat:@"HH:mm:ss"];
    } else {
        [formatter setDateFormat:@"mm:ss"];
    }
    NSString *showtimeNew = [formatter stringFromDate:d];
    return showtimeNew;
}

#pragma mark 设置时间轴最大时间
- (void)setMaxDuratuin:(float)duration{
    _totalTime = duration;
//    self.timeLabel.text = [self convertTime:duration];
}
//销毁player,无奈之举 因为avplayeritem的制空后依然缓存的问题。
- (void)destroyPlayer {
    [self.playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
    [self.playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    [self.playerItem removeObserver:self forKeyPath:@"status"];
    [self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
    [self.player removeObserver:self forKeyPath:@"rate"];
    [self.player removeTimeObserver:self.timeObserver];
    
    self.playerItem = nil;
    self.player = nil;
    
    self.playerStatus = VedioStatusPause;
    //    self.timeNowLabel.text = @"00:00";
}
#pragma mark 播放失败
-(void)playerFailed{
    NSLog(@"播放失败");
    [self destroyPlayer];
}

@end
